package com.ecoolex.discount.sales.ws;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.Service;
import org.assertj.core.util.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.PropertyMapper;

import com.ecoolex.discount.sales.core.external.v2.YWExternalService;
import com.ecoolex.discount.sales.core.external.v2.pojo.GetGiftCardListResponse;
import com.ecoolex.discount.sales.core.manager.YWGiftCardManager;
import com.ecoolex.discount.sales.entity.YWGiftCard;
import com.ecoolex.discount.sales.pojo.GetGiftCardDTO;

@Service
public class YWGiftCardServiceImpl implements YWGiftCardService {

	@Autowired
	YWGiftCardManager ywGiftCardManager;

	@Autowired
	YWExternalService ywExternalService;

	final static BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100);

	final static Function<BigDecimal, BigDecimal> DIVIDE_ONE_HUNDRED = (v) -> v.divide(ONE_HUNDRED);

	/**
	 * 对折扣率更新转换 BigDecimal discount =
	 * card.getCardDiscountPercent().divide(BigDecimal.valueOf(100));
	 * cardDTO.setCardDiscountPercent(BigDecimal.ONE.subtract(discount));
	 */

	@Override
	public List<GetGiftCardDTO> getAllGiftCards(String channelId) {
		String token = ywExternalService.getToken(channelId);
		GetGiftCardListResponse resp = ywExternalService.getGiftCardList(token);
		List<GetGiftCardDTO> getGiftCardDTOS = Collections.EMPTY_LIST;
		if (Objects.nonNull(resp) && YWExternalService.SUCCESS.equals(resp.getErrno())) {
			List<GetGiftCardListResponse.GiftCard> cards = resp.getData();
			if (CollectionUtils.isNotEmpty(cards)) {
				getGiftCardDTOS = cards.stream().map(card -> {
					GetGiftCardDTO cardDTO = new GetGiftCardDTO();
					BeanUtils.copyProperties(card, cardDTO);
					PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
					mapper.from(card::getUpdateTime).toCall(() -> {
						cardDTO.setUpdateTime(Date.from(Instant.ofEpochSecond(card.getUpdateTime())));
					});
					mapper.from(card::getFaceValue).to(faceVale -> cardDTO.setFaceValue(faceVale.divide(ONE_HUNDRED)));
					mapper.from(card::getCardMinValue)
							.to(minValue -> cardDTO.setCardMinValue(minValue.divide(ONE_HUNDRED)));
					mapper.from(card::getCardMaxValue)
							.to(maxValue -> cardDTO.setCardMaxValue(maxValue.divide(ONE_HUNDRED)));
					mapper.from(card::getStoreId).whenHasText()
							.to(storeId -> cardDTO.setStoreData(Arrays.asList(storeId)));
					if ("USD".equalsIgnoreCase(card.getCurrency())) {
						cardDTO.setCurrency(4);
					}
					else {
						cardDTO.setCurrency(0);
					}
					return cardDTO;
				}).collect(Collectors.toList());
			}
		}
		return getGiftCardDTOS;
	}

	@Override
	public List<GetGiftCardDTO> getAllGiftCardsFromDB() {
		List<YWGiftCard> cards = ywGiftCardManager.getAllGiftCards();
		if (!CollectionUtils.isEmpty(cards)) {
			List<GetGiftCardDTO> cardDTOS = cards.stream().map(card -> {
				GetGiftCardDTO cardDTO = new GetGiftCardDTO();
				BeanUtils.copyProperties(card, cardDTO);
				PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
				mapper.from(card::getLastModifiedTime).to(cardDTO::setUpdateTime);
				mapper.from(card::getFaceValue).as(DIVIDE_ONE_HUNDRED).to(cardDTO::setFaceValue);
				mapper.from(card::getCardMinValue)
						.to(minValue -> cardDTO.setCardMinValue(minValue.divide(ONE_HUNDRED)));
				mapper.from(card::getCardMaxValue)
						.to(maxValue -> cardDTO.setCardMaxValue(maxValue.divide(ONE_HUNDRED)));
				mapper.from(card::getStoreId).whenHasText()
						.to(storeId -> cardDTO.setStoreData(Arrays.asList(storeId)));
				return cardDTO;
			}).collect(Collectors.toList());
			return cardDTOS;
		}
		return Lists.<GetGiftCardDTO> emptyList();
	}
}
